﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Clipper.Model;
using System.Threading;
using Global;
using System.Windows;

using Communication;
using Clipper.Model.EnumModel;
using Clipper.Model.DataBaseModel;
using static Clipper.Model.DataBaseModel.DisplayCup;
using System.Collections;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace Clipper.BLL.DetectChain
{
    /// <summary>
    /// 检测仓
    /// </summary>
    public class DetectionHouse : ApplianceComponent
    {
        #region  变量和属性
        DetectResult mResultBll = new DetectResult();

        static ControlStatusEnum detectionStatus;
        /// <summary>
        /// 状态
        /// </summary>
        public override ControlStatusEnum DetectionStatus
        {
            get
            {
                return detectionStatus;
            }
            set
            {
                detectionStatus = value;
            }
        }

        static AutoResetEvent mPause = new AutoResetEvent(false);//暂停
        static bool mIsPause;
        /// <summary>
        /// 获得或设置模块暂停状态
        /// </summary>
        public static bool IsPause
        {
            get
            {
                return mIsPause;
            }
        }
        /// <summary>
        /// 光电检测获得的发光值,由DetectChainHelper赋值
        /// </summary>
        public static int CurrentLightValue
        {
            get;
            set;
        }
        /// <summary>
        /// 检测控制
        /// </summary>
        public static DetectControl DetectControl = new DetectControl();

        #endregion

        BLL.DataBaseBLL.CupDetectResultInfomation mbll = new BLL.DataBaseBLL.CupDetectResultInfomation();
        DataBaseBLL.StandardCurveData standardBll = new DataBaseBLL.StandardCurveData(); //标准曲线的类

        ReactionCup detectCupList = new ReactionCup();

        public DetectionHouse()
        {
            PositionCode = 76;
        }
        public override void Run(ReactionCup cup)
        {
            if (ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].getStatus() == CheckCancelEnum.CANCEL)
            {
                ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].setStatus(CheckCancelEnum.NOTCAN);

                ServiceProvider.CupStrip[cup.StripID].Cups[cup.CupSeatID].setStatus(Model.DetectionModel.Cup.CupHoleStatusEnum.END);
                ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].CupStatus = "取消";
                int gg = 0;
                for (int kk = 0; kk < ServiceProvider.CupStrip[cup.StripID].Cups.Count; kk++)
                {

                    if (ServiceProvider.CupStrip[cup.StripID].Cups[kk].getStatus() == Model.DetectionModel.Cup.CupHoleStatusEnum.END)
                        gg++;
                    if (gg == 4)
                        ServiceProvider.CupStrip[cup.StripID].setStatus(Model.DetectionModel.CupStrip.ReactionStripStatusEnum.UNLOAD);
                }
                return;

            }
            else
            {
                //此段为获取数据段
                //cup.StripID  分配的反应条号    加样位置
                // cup.CupSeatID 分配的反应杯号
                // 0,0 -4
                // 0,1 -3
                // 0,2 -2
                // 0,4 -1
                // 1,0 -5
                // 1,1 -6 
                int ADnum = 0;
                short ADcan = 90;

                if (cup.StripID % 2 == 0)
                {
                    ADnum = 4 - cup.CupSeatID;
                }
                else
                {
                    ADnum = 5 + cup.CupSeatID;
                }
                if (cup.StripID > 1)
                {
                    ADcan = 87;
                }

                //  
                double tickms = (DateTime.Now - cup.RecordTime).TotalMilliseconds;

                int backNum = Convert.ToInt32(tickms / 100 + 1);
                //cup.RecordTime = DateTime.Now;

                int gettingdata_time = cup.DetectItemModel.detectTime - backNum;


                int cupIndex = cup.StripID * 4 + cup.CupSeatID;
                string commandstr = "1AD" + ADnum.ToString() + "\r";

                //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

                for (int ll = 0; ll < backNum; ll++)
                {
                    cup.DetectResultList.Add(0);
                    cup.DetectResultTimeList.Add(Convert.ToInt32(ll * (tickms / backNum)));
                }
                bool toCheckStopFlag = true;
                int startTimeCount = gettingdata_time;
                int countBreak = 0;
                while (gettingdata_time > 0)
                {
                    DateTime startTime = DateTime.Now;
                    ServiceProvider.Monitor.DisplayCup[cupIndex].CupStatus = "获取数据..." + gettingdata_time.ToString();

                    cup.DetectResultTimeList.Add(Convert.ToInt32((DateTime.Now - cup.RecordTime).TotalMilliseconds));

                    Can.SendCan(ADcan, commandstr);
                    Thread.Sleep(180);

                    gettingdata_time = gettingdata_time - 2;
                    if (ADcan == 87)
                    {
                        cup.DetectResultList.Add(Can.AD2result[ADnum - 1]);
                        System.Diagnostics.Debug.WriteLine(ADnum + "=1==========>" + Can.AD2result[ADnum - 1]);
                    }
                    else
                    {
                        cup.DetectResultList.Add(Can.AD1result[ADnum - 1]);
                        System.Diagnostics.Debug.WriteLine(ADnum + "=2=========>" + Can.AD1result[ADnum - 1]);
                    }


                    //判断是否取消
                    if (ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].getStatus() == CheckCancelEnum.CANCEL)
                    {
                        ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].setStatus(CheckCancelEnum.NOTCAN);

                        ServiceProvider.CupStrip[cup.StripID].Cups[cup.CupSeatID].setStatus(Model.DetectionModel.Cup.CupHoleStatusEnum.END);
                        ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].CupStatus = "取消";
                        int ggd = 0;
                        for (int kk = 0; kk < ServiceProvider.CupStrip[cup.StripID].Cups.Count; kk++)
                        {

                            if (ServiceProvider.CupStrip[cup.StripID].Cups[kk].getStatus() == Model.DetectionModel.Cup.CupHoleStatusEnum.END)
                                ggd++;
                            if (ggd == 4)
                                ServiceProvider.CupStrip[cup.StripID].setStatus(Model.DetectionModel.CupStrip.ReactionStripStatusEnum.UNLOAD);
                        }
                        return;
                    }


                    //此处添加判断曲线的斜率
                    //if (toCheckStopFlag)
                    //{
                    //    if ((gettingdata_time <= (int)startTimeCount * 0.4 && gettingdata_time > (int)startTimeCount * 0.4 - 2) || (gettingdata_time <= (int)startTimeCount * 0.3 && gettingdata_time > (int)startTimeCount * 0.3 - 2))
                    //    {
                    //        BackgroundWorker backWork = new BackgroundWorker();
                    //        backWork.DoWork += (ss, ee) =>
                    //        {
                    //            int D_value = cup.DetectResultList[cup.DetectResultList.Count - 1] - cup.DetectResultList.Min();  //末尾值与最小值的差
                    //            List<int> elt = new List<int>();
                    //            for (int i = 0; i < 30; i += 3)
                    //            {
                    //                elt.Add(cup.DetectResultList[cup.DetectResultList.Count - 2 - i] - cup.DetectResultList.Min());
                    //            }
                    //            foreach (int one in elt)
                    //            {
                    //                if (System.Math.Abs(one - D_value) < D_value * 0.08)
                    //                {
                    //                    countBreak++;
                    //                    if (countBreak > 7)
                    //                    {
                    //                        //此处延时8秒检测
                    //                        if (gettingdata_time > 80)
                    //                        {
                    //                            gettingdata_time -= 80;
                    //                        }
                    //                        toCheckStopFlag = false;
                    //                        break;
                    //                    }
                    //                }
                    //            }
                    //        };
                    //        //backWork.RunWorkerCompleted += (ss, ee) =>
                    //        //{

                    //        //};
                    //        backWork.RunWorkerAsync();
                    //    }
                    //    if (countBreak > 7)
                    //    {
                    //        countBreak = 0;
                    //       // break;
                    //    }
                    //}
                    //===============
                }
                tickms = (DateTime.Now - cup.RecordTime).TotalMilliseconds;

                System.Diagnostics.Debug.WriteLine("==========>" + tickms);

                if (cup.DetectItem.Equals("DD") || cup.DetectItem.Equals("DDTEST"))
                {
                    cup.DetectResult = (cup.DetectResultTimeList[Coagulation_method.GetOD(cup.DetectResultList, backNum)] / 1000.0f).ToString("#.##");
                    //cup.DetectResult = ServiceProvider.Algorithmclass.GetOD(cup.DetectResultList, cup.DetectResultTimeList).ToString("#.##");
                }
                else
                {
                    //int a = ServiceProvider.Algorithmclass.GetSec(cup.DetectResultList, backNum);

                    cup.DetectResult = (cup.DetectResultTimeList[ServiceProvider.Algorithmclass.GetSec(cup.DetectResultList, backNum)] / 1000.0f).ToString("#.#");
                }



                //根据加样位置，定时发送信息到相关 AD通道号，截取获得的信息并保存
                //测量数据根据 对应实验 分析 并给出结果
                //完成后 置
                //把孔位号置为END ,判断整条是否完成
                Console.WriteLine("数据采集操作： 样本号：" + cup.SampleInfoID.ToString() + "\r" +
                                           "条号：" + cup.StripID.ToString() + "\r" +
                                           "杯号：" + cup.CupSeatID.ToString() + "\r"
                                           );


                //cup.StripID*4 + cup.CupSeatID  对应AD信息 获取 根据检测时间获取



                ServiceProvider.CupStrip[cup.StripID].Cups[cup.CupSeatID].setStatus(Model.DetectionModel.Cup.CupHoleStatusEnum.END);
                int gg = 0;
                for (int kk = 0; kk < ServiceProvider.CupStrip[cup.StripID].Cups.Count; kk++)
                {

                    if (ServiceProvider.CupStrip[cup.StripID].Cups[kk].getStatus() == Model.DetectionModel.Cup.CupHoleStatusEnum.END)
                        gg++;
                    if (gg == 4)
                        ServiceProvider.CupStrip[cup.StripID].setStatus(Model.DetectionModel.CupStrip.ReactionStripStatusEnum.UNLOAD);
                }
                string montorStr = "";
                try
                {
                    double resultDe = Convert.ToDouble(cup.DetectResult);
                    foreach (Model.ResultReference resulf in ServiceProvider.Monitor.MResultReferenceList)
                    {
                        if (resulf.DetectItem.Equals(cup.DetectItem))
                        {
                            if (resultDe < Convert.ToInt32(resulf.RRsLowlimit))
                            {
                                montorStr = "--↓";
                            }
                            else if (resultDe > Convert.ToInt32(resulf.RRsToplimit))
                            {
                                montorStr = "--↑";
                            }
                            else if (resultDe < Convert.ToInt32(resulf.RRsToplimit) || resultDe < Convert.ToInt32(resulf.RRsLowlimit))
                            {
                                montorStr = "--√";
                            }
                            break;
                        }
                    }
                }
                catch
                {
                }
                ServiceProvider.Monitor.DisplayCup[cup.StripID * 4 + cup.CupSeatID].CupStatus = "结束";

                //StandardCurveData standardModel =standardBll.GetModel(cup.DetectItemModel.detectItem);
                //数据计算 
                // cup.detectResultList 处理
                //收集数据
                Model.DataBaseModel.CupDetectResultInformation detectResult = new Model.DataBaseModel.CupDetectResultInformation();
                detectResult.CupHoleNum = cup.StripID * 4 + cup.CupSeatID + 1;
                detectResult.SampleInfoID = (int)cup.SampleInfoID;
                detectResult.DetectItem = cup.DetectItemModel.detectItem;
                detectResult.DetectTime = DateTime.Now;
                detectResult.DetectResult = cup.DetectResult;
                detectResult.DetectResultList = cup.DetectResultList;
                detectResult.DetectresultTimelist = cup.DetectResultTimeList; //增加时间集合

                //给定标的集合添加结果
                //detectResult.Activity= 
                if (!cup.DetectResult.Equals("") && ServiceProvider.ISCheckSave)
                {
                    ServiceProvider.shortCalibraList.Add(Convert.ToDouble(cup.DetectResult));
                }

                //存取数据
                mbll.Add(detectResult);
                if (Application.Current != null)
                {
                    Application.Current.Dispatcher.Invoke((Action)(() =>
                   {
                       detectResult.DetectResult = cup.DetectResult + montorStr;
                       ServiceProvider.Monitor.DetectResultList.Add(detectResult);
                   }));
                }

                //此处给当天做的实验添加结果
                getDetectValue(ServiceProvider.Monitor.DetectResultListToady, cup);

                //if (cup.IsSaveResult)
                //{
                //    //计算出结果以后往数据库中存取得到的检测结果
                //    ServiceProvider.StandardResult[cup.SampleInfoID, 0] = 100 / Math.Pow(2, cup.SampleInfoID - 1) + ""; //记录浓度
                //    ServiceProvider.StandardResult[cup.SampleInfoID, 1] = cup.DetectResult; //记录检测结果
                //}
            }
        }
        //保存检测结果
        public void SaveDetectResult(ReactionCup strip)
        {
            //foreach (ReactionCup cup in strip.ReactionCupList)
            //{
            //    Model.DetectResult resultModel = new Model.DetectResult();
            //    resultModel.lightValue = cup.LightValue;
            //    resultModel.DetectItem = cup.DetectItem;
            //    resultModel.SampleID = cup.SampleInfoID;
            //    resultModel.checkDatetime = strip.DetectEndTime;
            //    resultModel.ResultState =(int)cup.DetectProcess;
            //    mResultBll.Add(resultModel);

            //}
        }


        public void getDetectValue(ObservableCollection<CupDetectResultInformation> detectToday, ReactionCup cup)
        {
            foreach (CupDetectResultInformation model in detectToday)
            {
                if ((model.SampleInfoID == cup.SampleInfoID) && (model.DetectItem == cup.DetectItem) && (model.ChangeFlag == true))
                {
                    model.DetectResult = cup.DetectResult;    //给结果赋值
                    model.DetectResultList = cup.DetectResultList;  //检测结果集合
                    model.DetectresultTimelist = cup.DetectResultTimeList; //检测时间集合
                    model.CupHoleNum = cup.StripID * 4 + cup.CupSeatID + 1; // 杯子的孔位
                    model.DetectTime = DateTime.Now;  //检测时间
                    model.ChangeFlag = false;
                    return;
                }
            }
        }


        /// <summary>
        /// 暂停/恢复
        /// </summary>
        /// <param name="isPause">暂停true,恢复false</param>
        public static void Pause(bool isPause)
        {
            mIsPause = isPause;
            DetectControl.IsPause = isPause;
        }
        public override void Simulate(ReactionCup strip)
        {
            if (IsPause)//局部暂停
            {
                mPause.WaitOne();
            }
            SaveDetectResult(strip);//保存结果
            Thread.Sleep(ServiceProvider.DetectionHoouseSleepTime);
        }
        /// <summary>
        /// 调试
        /// </summary>
        public static void RunEngineer()
        {
            //DetectionHouse detect = new DetectionHouse();
            //ReactionStrip strip = new ReactionStrip();
            //strip.DetectEndTime = DateTime.Now;
            //for (int i = 0; i < 8;i++)
            //{
            //    ReactionCup cup = new ReactionCup();
            //    cup.SampleInfoID = i;
            //    cup.DetectItem = "TTT";
            //    DetectControl.WaitStatus(DetectControl.PositionCup());
            //    cup.LightValue = DetectionHouse.CurrentLightValue;
            //    strip.ReactionCupList.Add(cup);
            //}
            ////DetectControl.Imbibe();
            //detect.SaveDetectResult(strip);//保存结果
            //DetectControl.WaitStatus(DetectControl.ThrowStrip());
            //DetectControl.WaitStatus(DetectControl.GoIncubation());
        }


        #region // 模块运行控制，Anry
        private static Arm mArmDT = new Arm("DT", "15");                    // 检测臂
        private static Arm mArmF = new Arm("F", "15");                      // 滑轨F
        private static ControlStatusEnum mStatusDT = ControlStatusEnum.IDLE;        // 检测臂状态
        /// <summary>
        /// 检测臂
        /// </summary>
        public static Arm ArmDT
        {
            get { return mArmDT; }
            set { mArmDT = value; }
        }

        /// <summary>
        /// 滑轨F
        /// </summary>
        public static Arm ArmF
        {
            get { return mArmF; }
            set { mArmF = value; }
        }

        private void RunControl(ReactionStrip strip)
        {
            for (int i = 0; i < strip.ReactionCupList.Count; i++)
            {
                // 如果模块需要暂停，则暂停模块运行，等待外部改变此状态且继续模块运行
                if (IsPause)
                {
                    mPause.WaitOne();
                }

                // 如果滑轨F空闲，则滑轨F将反应条下一个杯移到加底物位置
                if (ServiceProvider.gStatusSlideF == ControlStatusEnum.IDLE)
                {
                    Transportation.AssayCupFeeding('F', (byte)(i + 1));
                    ServiceProvider.gStatusSlideF = ControlStatusEnum.BUSY;
                }

                // 循环等待，直到滑轨D状态为空闲，跳出循环
                while (ServiceProvider.gStatusSlideF == ControlStatusEnum.BUSY)
                {
                    System.Threading.Thread.Sleep(ServiceProvider.gInteralmSec);
                }

                // 如果模块需要暂停，则暂停模块运行，等待外部改变此状态且继续模块运行
                if (IsPause)
                {
                    mPause.WaitOne();
                }

                // 如果检测臂空闲，则进行检测,将检测臂的状态设置为忙
                if (mStatusDT == ControlStatusEnum.IDLE)
                {
                    mArmDT.Detect();
                    mStatusDT = ControlStatusEnum.BUSY;
                }

                // 循环等待，直到滑轨D状态为空闲，跳出循环
                while (mStatusDT == ControlStatusEnum.BUSY)
                {
                    System.Threading.Thread.Sleep(ServiceProvider.gInteralmSec);
                }

                // 需要保存反馈的结果???
            }

            if (IsPause)
            {
                mPause.WaitOne();
            }

            // 检测完成后，将反应条送到废料仓
            if (ServiceProvider.gStatusSlideF == ControlStatusEnum.IDLE)
            {
                Transportation.MoveStripFromDetectingToTrashCan();
                ServiceProvider.gStatusSlideF = ControlStatusEnum.BUSY;
            }

            // 循环等待，直到滑轨D状态为空闲，跳出循环
            while (ServiceProvider.gStatusSlideF == ControlStatusEnum.BUSY)
            {
                System.Threading.Thread.Sleep(ServiceProvider.gInteralmSec);
            }
        }
        #endregion // 模块运行控制，Anry
    }
}
